<?php
namespace Swiftx\Bundle\WeChat\System;
use Swiftx\Component\Bundle\Kernel as BundleKernel;
use Swiftx\Interfaces\Application\Kernel as AppKernel;
use Swiftx\Interfaces\Orm\Entity;
use Swiftx\Interfaces\Orm\Manager as ManagerInterface;
use Swiftx\Interfaces\Bundle\Kernel;
use Swiftx\Component\Orm\Manager;
use Swiftx\Interfaces\Router\Collection;
use Swiftx\Interfaces\Application\Server;


/**
 * 控制台UI框架Bundle模块
 */
class Bundle extends BundleKernel implements Kernel{

    /**
     * 路由分发器
     * @var Collection
     */
    protected $router;

    /**
     * 服务器组件
     * @var Server
     */
    protected $server;

    /**
     * 注入路由器
     * @param Server $server
     * @param Collection $collection
     */
    public function __construct(Server $server, Collection $collection){
        $this->server = $server;
        $this->router = $collection;
        $this->rootPath = realpath(__DIR__.'/../../');
    }

    /**
     * 模块引导
     * @param AppKernel $kernel
     */
    public function boot(AppKernel $kernel){
        // 构造模块配置对象
        $config = new Config($kernel->getConfig(), $this);
        $kernel->bindEntity(Config::class, $config , true);

        /** @var Storage $storage 构造贮存器 */
        $storage = $kernel->create(Storage::class);
        $dir = $this->server->getEvn('PATH_RUNTIME').'/cache/'.$this->getName();
        $storage->setCacheDir($this->server->parsePath($dir));
        $dir = $this->server->getEvn('PATH_RUNTIME').'/build/'.$this->getName();
        $storage->setBuildDir($this->server->parsePath($dir));
        $storage->setResourceDir($this->server->parsePath($config->get('resource.public')));
        $storage->setResourceMap($config->get('resource.url'), $this->getRootPath().'/resource');
        $kernel->bindEntity(Storage::class, $storage , true);

        // 注册所有路由接口
        $interfacesDir = $this->getRootPath().'/interfaces/Controller';
        $classBase = 'Swiftx\\Bundle\\WeChat\\Interfaces\\Controller';
        $this->loaderDir($interfacesDir, $classBase, function(string $class_name){
            $this->router->parseAnnotation($class_name);
        });

        /** @var ManagerInterface $orm */
        $orm = $kernel->create(Manager::class);
        $kernel->bindEntity(ManagerInterface::class, $orm, true);

        // 进行数据库连接操作
        $orm->connection(
            'mysql', $config->get('database.host'),
            $config->get('database.name'),
            $config->get('database.user'),
            $config->get('database.password')
        );
        // 设置缓存目录
        $dir = $this->server->getEvn('PATH_RUNTIME').'/cache/'.$this->getName().'/orm';
        $orm->setRuntimeDir($dir);

        // 解析模型对象配置
        $evn['prefix'] = $config->get('database.prefix');
        $orm->registerMappingConfig($config->dir('config/orm.xml'));

        // 标记引导完成
        $this->booted = true;
    }

    /**
     * 递归遍历目录
     * @param string $path
     * @param string $class
     * @param callable $foo
     */
    protected function loaderDir(string $path, string $class,callable $foo){
        $file_list = scandir($path);
        unset($file_list[0]);
        unset($file_list[1]);
        foreach($file_list as $value){
            $new_path = $path.DIRECTORY_SEPARATOR.$value;
            $new_class = $class.'\\'.explode('.',$value)[0];
            if(is_dir($new_path))
                $this->loaderDir($new_path, $new_class, $foo);
            else call_user_func($foo, $new_class);
        }
    }

    /**
     * 项目构建
     */
    public function build(){

    }

}